/*********************************************************************
 clase Marcador
 * un marcador es la representacion grafica de un componente en el
 * mapa de google
 ********************************************************************/
function hidmarcador(puntoCentral, nombre, rutaBase, tipoPuntoMonitoreo)
{
    var puntoCentral = puntoCentral;
    var nombre = nombre;
    var rutaBase = rutaBase;
    var tipoPuntoMonitoreo = tipoPuntoMonitoreo;

    this.CrearMarcador = function (puntoCentral1, nombre1)
    {
        var marker = new google.maps.Marker({
            position: puntoCentral1,
            title:nombre1,
            draggable:true
        });
        return marker;
    };
    this.AgregarMarcador = function ()
    {
        //si ya fue seleccionado la grafica de algun tipo de componente
        if(document.getElementById("marcador").value != "")
        {
            var ruta = ExtraerValor("marcador");
            var componenteunico = ExtraerValor("marcadorunico");
            var marker = this.CrearMarcador(puntoCentral, nombre);

            var componente = this.CrearComponente(ruta, componenteunico, marker);

            //si el valor de la ruta existe se asigna  la imagen correspondiente al marcador
            if(this.ExisteRuta(ruta))
            {
                ruta = rutaBase + ruta + ".jpg";
                marker.setIcon(ruta);
            }

            //vericamos si es un componente nodo o arista
            if(this.EsComponenteSingular(componenteunico))
            {
                marker =  this.AgregarCamposMarcador(componente, marker);
                marker = this.AgregarListaEventos(marker);
                markersArray.push(marker);
            }
        }
    };
    this.AgregarEventosMarcador = function (componente)
    {
        //se crea un marcador con los datos contenidos en el componente
        var myLatlng = new google.maps.LatLng(componente.latitud,componente.longitud);
        var marker = this.CrearMarcador(myLatlng, 'Componente');
        marker.ide = componente.ide;
        marker.setIcon(rutaBase + componente.tipo + ".jpg");

        //verificamos que sea un componente nodo
        if(this.EsComponenteSingular(componente.tipouni))
        {
            marker.posicionactual = puntoCentral;
            marker.latitud = componente.latitud;
            marker.longitud = componente.longitud;

            //Agregamos eventos al marcador para click, doble click, etc.
            this.AgregarEventoMarcador(marker,'click',function(){
                AgregarLinea(marker);
            });
            this.AgregarEventoMarcador(marker,'dblclick',function(){
                EliminarMarcador(marker);
            });
            this.AgregarEventoMarcador(marker,'rightclick',function(){
                VentanaMarcador(marker);
            });
            this.AgregarEventoMarcador(marker,'dragend',function(){
                ActualizarMarcador(marker);
            });
            this.AgregarEventoMarcador(marker,'drag',function(){
                ActualizarPolylinesMarcador(marker);
            });

            //agregamos el marcador creado a la lista de marcadores
            markersArray.push(marker);
        }
    };
    this.AgregarEventoMarcador = function (marcador, evento, funcion)
    {
        google.maps.event.addDomListener(marcador, evento, funcion);
    };
    this.AgregarListaEventos = function (marcador)
    {
        this.AgregarEventoMarcador(marcador,'click',function(){
            AgregarLinea(marcador);
        });
        this.AgregarEventoMarcador(marcador,'dblclick',function(){
            EliminarMarcador(marcador);
        });
        this.AgregarEventoMarcador(marcador,'rightclick',function(){
            VentanaMarcador(marcador);
        });
        this.AgregarEventoMarcador(marcador,'dragend',function(){
            ActualizarMarcador(marcador);
        });
        this.AgregarEventoMarcador(marcador,'drag',function(){
            ActualizarPolylinesMarcador(marcador);
        });
        return marcador;
    }
    this.AgregarLinea = AgregarLinea;
    this.VentanaMarcador = VentanaMarcador;
    this.EliminarMarcador = EliminarMarcador;
    this.ActualizarMarcador = ActualizarMarcador;
    this.ActualizarPolylinesMarcador = ActualizarPolylinesMarcador;
    this.CrearComponente = function(rutadeimagenes, componenteunico, marcador)
    {
        var componente = new hidcomponente(0, rutadeimagenes, componenteunico, marcador.getPosition().lat(), marcador.getPosition().lng(), marcador.title, tipoPuntoMonitoreo);
        componente.ideparcial = componente.hidcomp_nuevoIde(componentes,lineArray);
        return componente;
    };
    this.ExisteRuta = function (ruta)
    {
        if(ruta)
            return true;
        else
            return false;
    }
    this.EsComponenteSingular = function (flagcomponenteunico)
    {
        if(flagcomponenteunico == "true")
            return true;
        else
            return false;
    }
    this.AgregarCamposMarcador = function (componente, marcador)
    {
        //agregamos campos correpondientes al componente que no posee el marcador
        componentes.push(componente);
        var posicionComp = componente.hidcomp_findByLatLng(componentes,marcador);
        marcador.posicionComp = posicionComp;
        marcador.posicionactual = puntoCentral;
        marcador.latitud = componente.latitud;
        marcador.longitud = componente.longitud;
        return marcador;
    }
}

function AgregarLinea(marker)
{
    //Se debe verificar que se trata de un componente de varios elementos
    if( ExtraerValor("marcadorunico") == "false")
    {
        //se debe obtener el punto de origen y destino
        //se verifica que no se haya seleccionado el punto de origen, para elegirlo
        if(ExistenInicioFinLinea("inilinea","inilinea2"))
        {
            AsignarValor("inilinea",marker.posicionactual.lat());
            AsignarValor("inilinea2",marker.posicionactual.lng());
            marker = AlmacenarPosicionComponente(marker);
            AsignarValor("marcadorinicial",marker.posicionComp);
        }
        else
        {
            AgregarNombreLinea(marker);
        }
    }
};

function ExistenInicioFinLinea(identificador1, identificador2)
{
    //se debe verificar si existen el nodo de inicio y el de fin
    if(ExtraerValor(identificador1) == "" && ExtraerValor(identificador2) == "")
        return true;
    else
        return false;
}

function AlmacenarPosicionComponente(marcador)
{
    //se debe obtener la posicion dentro del arreglo de componentes que corresponde al marcador
    var cmp = new hidcomponente(1,1,1,1);
    var posicionComp = cmp.hidcomp_findByLatLng(componentes,marcador);
    marcador.posicionComp = posicionComp;
    return marcador;
}

function CrearLinea(marcador, nombreComponente, tipoPuntoMonitoreo)
{
    //cuando se trata del punto de destino se deben obtener los valores del punto de origen y junto con los
    //datos del punto de destino generar un arreglo con ambos datos para finalmente agregarlo al arreglo de
    //lineas
    var latitud1 = parseFloat(ExtraerValor("inilinea"));
    var longitud1 = parseFloat(ExtraerValor("inilinea2"));
    var tipo = ExtraerValor("marcador");

    var linea = [];
    linea.push(latitud1);
    linea.push(longitud1);
    linea.push(marcador.posicionactual.lat());
    linea.push(marcador.posicionactual.lng());
    linea.push(tipo);
    linea.push(0);
    marcador = AlmacenarPosicionComponente(marcador);
    var ideinicial = ExtraerValor("marcadorinicial");

    //ides de los nodos
    linea.push(componentes[ideinicial].ide);
    linea.push(componentes[marcador.posicionComp].ide);
    linea.push(nombreComponente);
    linea.push(tipoPuntoMonitoreo);

    return linea;
}

function VentanaMarcador(marker)
{
    var contentString = '<div id="content"><a onclick="deleteOverlays()">OK</a></div>';
    var infowindow = new google.maps.InfoWindow({
        content: contentString
    });
    infowindow.open(mapa,marker);
};

function EliminarMarcador(marker)
{
    //se debe encontrar el componente correspondiente al marcador y agregarlo a la lista de eliminados
    //se debe borrar el marcador(grafico) del mapa
    ActualizarListaEliminados(marker);
    marker.setMap(null);

    //se debe actualizar la lista de marcadores
    ActualizarListaMarcadores(marker);

    //eliminar lineas conectadas a un marcador
    EliminarLineasConectadasMarcador(marker);
};

function ActualizarListaEliminados(marcador)
{
    //se debe encontrar el componente correspondiente al marcador y agregarlo a la lista de eliminados
    var cmp = new hidcomponente(1,1,1,1);
    eliminadosArray.push(cmp.hidcomp_find(componentes,marcador));
}

function ActualizarListaMarcadores(marcador)
{
    //se debe actualizar la lista de marcadores
    var ListaMarcadoresTemporal = [];
    for (i in markersArray)
    {
        if(markersArray[i].getPosition().equals(marcador.getPosition()) == false)
        {
            //se crea una lista temporal de marcadores
            ListaMarcadoresTemporal.push(markersArray[i]);
        }
    }

    //se asigna la lista temporal de marcadores al arreglo original de marcadores
    markersArray.length = ListaMarcadoresTemporal.length;
    markersArray = ListaMarcadoresTemporal;
}

function EliminarLineasConectadasMarcador(marcador)
{
    //eliminar lineas conectadas a un marcador
    var hidaritmp = new hidarista(1,1,1,1,'');
    var lista = hidaritmp.hidari_find(lineArray, marcador);

    for (var i = 0; i < lista.length; i++)
    {
        //lista contiene la posicion del arreglo de polilineas
        //y el valor 0 o 1 para indicar si es inicio o fin
        var posicion = lista[i];
        EliminarLinea(posicion[0],poly[posicion[0]].idpoly);
    }
}

function ActualizarMarcador(marker)
{
    //se debe encontrar el componente correspondiente al marcador
    var posicionComponente = ObtenerPosicionMarcadorModificado(marker);

    //se debe actualizar las propiedades del componente
    componentes[posicionComponente].latitud = marker.getPosition().lat();
    componentes[posicionComponente].longitud = marker.getPosition().lng();
    marker.posicionactual = marker.getPosition();
};

function ObtenerPosicionMarcadorModificado(marcador)
{
    //se debe encontrar el componente correspondiente al marcador
    var idemarcador = marcador.ide;
    var posicionMarcador;
    if(isNaN(idemarcador) == true)
    {
        posicionMarcador = marcador.posicionComp;
    }
    else
    {
        var cmp = new hidcomponente(1,1,1,1);
        var identificadorMarcador = parseInt(idemarcador);
        posicionMarcador = cmp.hidcomp_findById(componentes,identificadorMarcador);
    }
    return posicionMarcador;
}

function ActualizarPolylinesMarcador(marker)
{
    var lista = ObtenerLineasConectadasMarcador(marker);
    marker.posicionactual = marker.getPosition();

    for (var i = 0; i < lista.length; i++)
    {
        //lista contiene la posicion del arreglo de polilineas
        //y el valor 0 o 1 para indicar si es inicio o fin
        ActualizarLineas(lista,i,marker);
    }
};

function ObtenerLineasConectadasMarcador(marcador)
{
    var hidaritmp = new hidarista(1,1,1,1,'');
    var listaLineas = hidaritmp.hidari_find(lineArray, marcador);
    return listaLineas;
}

function ActualizarLineas(lista, posicionLista, marcador)
{
    //lista contiene la posicion del arreglo de polilineas
    //y el valor 0 o 1 para indicar si es inicio o fin
    var lineas = {"latitudorigen":0, "longitudorigen":1, "latitudfin":2, "longitudfin":3};
    var posicion = lista[posicionLista];
    var pathpolilinea = poly[posicion[0]].getPath();

    if(EsInicio(posicion[1]))
    {
        //si es el nodo de inicio, se almacena temporalmente el nodo de fin, se extrae los 2 nodos
        // y se ingresa el nuevo nodo, y finalmente el nodo temporal
        var nodoFin = pathpolilinea.getAt(1);
        pathpolilinea.pop();
        pathpolilinea.pop();
        pathpolilinea.push(marcador.getPosition());
        pathpolilinea.push(nodoFin);
        lineArray[posicion[0]][lineas.latitudorigen] = marcador.posicionactual.lat();
        lineArray[posicion[0]][lineas.longitudorigen] = marcador.posicionactual.lng();
    }
    else
    {
        //si es el nodo fin, simplemente se le extrae y se ingresa el nuevo
        pathpolilinea.pop();
        pathpolilinea.push(marcador.getPosition());
        lineArray[posicion[0]][lineas.latitudfin] = marcador.posicionactual.lat();
        lineArray[posicion[0]][lineas.longitudfin] = marcador.posicionactual.lng();
    }
}

function EsInicio(posicion)
{
    if(posicion == 0)
        return true;
    else
        return false;
}

function AgregarNombreLinea(marker)
{
    //construimos una ventana para el ingreso del nombre del componente arista
    var htmlBox = CrearVentanaModal("Nombre de Componente","300px","20px");
    var input = CrearInputText("text","30","30");
    var select = CrearComboSeleccion();
    var br = CrearSaltoDeLinea();
    var editBtn = CrearBoton("Agregar");
    var container = CrearContenedorVentana();

    container.appendChild(htmlBox);
    container.appendChild(input);
    container.appendChild(select);
    container.appendChild(br);
    container.appendChild(editBtn);

    //creamos una ventana de informacion con la ventana creada
    var infowindow = new google.maps.InfoWindow({
        content: container,
        position: marker.posicionactual
    });

    //asignamos el evento al boton de la ventana para 'click'
    google.maps.event.addDomListener(editBtn, "click", function() {
        input.readOnly = true;
        setTimeout(function () { infowindow.close(); }, 500);
        CrearContenidoLinea(marker, input.value, select.value);
    });

    infowindow.open(mapa);
}

function CrearContenidoLinea(marker, nombreComponente, tipoPuntoMonitoreo)
{
    var linea = CrearLinea(marker,nombreComponente, tipoPuntoMonitoreo);
    lineArray.push(linea);
    poly.push(null);
    AsignarValor("inilinea","");
    AsignarValor("inilinea2","");
    MostrarLineas();
}